/**
 * Claude模型适配器
 * 支持Claude-3系列模型
 */

import { BaseModelAdapter, ModelConfig, ModelResponse, StreamResponse } from './base-model-adapter';

export class ClaudeAdapter extends BaseModelAdapter {
  private apiKey: string;
  private baseUrl: string;

  constructor(config: ModelConfig, modelName: string) {
    super(config, modelName);
    this.apiKey = config.apiKey;
    this.baseUrl = config.baseUrl || 'https://api.anthropic.com/v1';
  }

  async generate(prompt: string, options?: Partial<ModelConfig>): Promise<ModelResponse> {
    const requestConfig = { ...this.config, ...options };
    
    try {
      const response = await fetch(`${this.baseUrl}/messages`, {
        method: 'POST',
        headers: {
          'x-api-key': this.apiKey,
          'Content-Type': 'application/json',
          'anthropic-version': '2023-06-01'
        },
        body: JSON.stringify({
          model: this.modelName,
          max_tokens: requestConfig.maxTokens,
          temperature: requestConfig.temperature,
          messages: [{ role: 'user', content: prompt }]
        })
      });

      if (!response.ok) {
        throw new Error(`Claude API error: ${response.status} ${response.statusText}`);
      }

      const data = await response.json();
      
      return {
        content: data.content[0].text,
        usage: {
          promptTokens: data.usage.input_tokens,
          completionTokens: data.usage.output_tokens,
          totalTokens: data.usage.input_tokens + data.usage.output_tokens
        },
        model: this.modelName,
        finishReason: data.stop_reason === 'end_turn' ? 'stop' : data.stop_reason,
        cost: this.estimateCost(data.usage.input_tokens, data.usage.output_tokens)
      };
    } catch (error) {
      console.error('Claude generation error:', error);
      throw error;
    }
  }

  async stream(
    prompt: string,
    onChunk: (chunk: StreamResponse) => void,
    options?: Partial<ModelConfig>
  ): Promise<void> {
    const requestConfig = { ...this.config, ...options };

    try {
      const response = await fetch(`${this.baseUrl}/messages`, {
        method: 'POST',
        headers: {
          'x-api-key': this.apiKey,
          'Content-Type': 'application/json',
          'anthropic-version': '2023-06-01'
        },
        body: JSON.stringify({
          model: this.modelName,
          max_tokens: requestConfig.maxTokens,
          temperature: requestConfig.temperature,
          messages: [{ role: 'user', content: prompt }],
          stream: true
        })
      });

      if (!response.ok) {
        throw new Error(`Claude API error: ${response.status} ${response.statusText}`);
      }

      const reader = response.body?.getReader();
      if (!reader) {
        throw new Error('Failed to get response reader');
      }

      const decoder = new TextDecoder();
      let buffer = '';

      while (true) {
        const { done, value } = await reader.read();
        
        if (done) {
          onChunk({ content: '', done: true });
          break;
        }

        buffer += decoder.decode(value, { stream: true });
        const lines = buffer.split('\n');
        buffer = lines.pop() || '';

        for (const line of lines) {
          if (line.startsWith('data: ')) {
            const data = line.slice(6);
            
            try {
              const parsed = JSON.parse(data);
              
              if (parsed.type === 'content_block_delta') {
                const content = parsed.delta?.text || '';
                onChunk({
                  content,
                  done: false
                });
              } else if (parsed.type === 'message_stop') {
                onChunk({ content: '', done: true });
                return;
              }
            } catch (e) {
              // 忽略解析错误
            }
          }
        }
      }
    } catch (error) {
      console.error('Claude streaming error:', error);
      throw error;
    }
  }

  async countTokens(text: string): Promise<number> {
    // Claude的token计算，简单估算
    return Math.ceil(text.length / 3.5);
  }

  estimateCost(promptTokens: number, completionTokens: number): number {
    // Claude-3 Sonnet定价
    const inputCost = (promptTokens / 1000) * 0.003;
    const outputCost = (completionTokens / 1000) * 0.015;
    return inputCost + outputCost;
  }

  async healthCheck(): Promise<boolean> {
    try {
      // Claude没有专门的健康检查端点，使用简单的请求测试
      const response = await fetch(`${this.baseUrl}/messages`, {
        method: 'POST',
        headers: {
          'x-api-key': this.apiKey,
          'Content-Type': 'application/json',
          'anthropic-version': '2023-06-01'
        },
        body: JSON.stringify({
          model: this.modelName,
          max_tokens: 1,
          messages: [{ role: 'user', content: 'test' }]
        })
      });
      return response.ok;
    } catch {
      return false;
    }
  }
}
